package com.marver.common.file;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

import com.marver.common.result.Result;
import com.marver.common.result.ResultStatus;
import com.marver.common.utils.PropUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


/**
 * OSS授权令牌
 * @author chenxiang
 * @version 2017-10-19
 */

@Service
public class OSSService {
	//oss的文件夹选择
	@Value("${oss.bucketName}")
	public String OSSBANKNAME;

	// 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
	public String REGION_CN_HANGZHOU = PropUtil.getProperty("oss.region");
	// 当前 STS API 版本
	public String STS_API_VERSION = PropUtil.getProperty("oss.sts_api_version");

	// 只有 RAM用户（子账号）才能调用 AssumeRole 接口
	// 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
	// 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
	private String accessKeyId = PropUtil.getProperty("oss.accessKeyId");
	private String accessKeySecret =PropUtil.getProperty("oss.accessKeySecret");
	// AssumeRole API 请求参数: RoleArn, RoleSessionName, Policy, and
	// DurationSeconds
	// RoleArn 需要在 RAM 控制台上获取
	private String roleArn = PropUtil.getProperty("oss.acs.ram");

	// RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
	// 但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符
	// 具体规则请参考API文档中的格式要求
	private String roleSessionName = PropUtil.getProperty("oss.roleSessionName");
	private String endpoint = PropUtil.getProperty("oss.endpoint");

	private AssumeRoleResponse response=null;

	// 如何定制你的policy?
	private String policy = "{\n" + "    \"Version\": \"1\", \n" + "    \"Statement\": [\n" + "        {\n"
			+ "            \"Action\": [\n" + "                \"oss:GetBucket\", \n"
			+ "                \"oss:GetObject\" \n" + "            ], \n" + "            \"Resource\": [\n"
			+ "                \"acs:oss:*:*:*\"\n" + "            ], \n" + "            \"Effect\": \"Allow\"\n"
			+ "        }\n" + "    ]\n" + "}";
	private ProtocolType protocolType = ProtocolType.HTTPS;

	public AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn,
			String roleSessionName, String policy, ProtocolType protocolType) throws ClientException {
		try {
			// 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
			IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
			DefaultAcsClient client = new DefaultAcsClient(profile);
			// 创建一个 AssumeRoleRequest 并设置请求参数
			final AssumeRoleRequest request = new AssumeRoleRequest();
			request.setVersion(STS_API_VERSION);
			request.setMethod(MethodType.POST);
			request.setProtocol(protocolType);
			request.setRoleArn(roleArn);
			request.setRoleSessionName(roleSessionName);
			request.setPolicy(policy);
			// 发起请求，并得到response
			final AssumeRoleResponse response = client.getAcsResponse(request);
			return response;
		} catch (ClientException e) {
			throw e;
		}
	}

	/**
	 * 获取OSS AccessKeySecret
	 * @return
	 * @throws ClientException
	 */
	public Result getAccessKeySecret() throws ClientException {
		Result result=new Result(ResultStatus.FAIL.getErrorCode());
		//if(response==null)
			response = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy, protocolType);
		List data=new ArrayList();
		Map map=new HashMap();
		map.put("accessKeySecret",response.getCredentials().getAccessKeySecret());
		map.put("accessKeyId",response.getCredentials().getAccessKeyId());
		map.put("securityToken",response.getCredentials().getSecurityToken());
		map.put("expiration",response.getCredentials().getExpiration());
		map.put("endpoint",endpoint);
		data.add(map);
		result=new Result(ResultStatus.SUCCESS.getErrorCode(),data);
		return result;
	}

	/**
	 * 根据key获取资源访问地址
	 * @param objectKey
	 * @return
	 * @throws ClientException
	 */
	public String getUrl(String objectKey) throws ClientException {
		//if(response==null)
			response = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy, protocolType);
		String accessKeyIds = response.getCredentials().getAccessKeyId();
		String accessKeySecrets = response.getCredentials().getAccessKeySecret();
		String securityToken = response.getCredentials().getSecurityToken();
		String endpoint = PropUtil.getProperty("oss.endpoint");
		OSSClient client = new OSSClient(endpoint, accessKeyIds, accessKeySecrets, securityToken);
		String bucketName = OSSBANKNAME;
		String key = objectKey;
		// 设置URL过期时间为1小时
		Date expiration = new Date(new Date().getTime() + 3600 * 1000);
		// 生成URL
		URL url = client.generatePresignedUrl(bucketName, key, expiration);
		String strurl=url.toString();
		return strurl;
	}

	/**
	 * 上传资源(本地文件)
	 * @param file
	 * @param imageName
	 * @param ossidcardurl
	 */
	public void uploadOssFile(File file, String imageName, String ossidcardurl){
		// 创建OSSClient实例
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);;
		// 上传文件
		ossClient.putObject(OSSBANKNAME, ossidcardurl, file);//"idcard/20170915095246_224.jpg"
		// 关闭client
		ossClient.shutdown();
	}

	/**
	 * 上传资源（文件流、网络流）
	 * @param inputStream
	 * @param imageName
	 * @param ossidcardurl
	 */
	public void uploadOssFile(InputStream inputStream, String imageName, String ossidcardurl){
		// 创建OSSClient实例
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);;
		// 上传文件流
		//InputStream inputStream = new FileInputStream("localFile");
		//上传网络流
		//InputStream inputStream = new URL("https://www.aliyun.com/").openStream();
		ossClient.putObject(OSSBANKNAME, ossidcardurl, inputStream);//"idcard/20170915095246_224.jpg"
		// 关闭client
		ossClient.shutdown();
	}


	/**
	 * houdongdong	2018-01-31
	 * 查询oss服务器文件路径(设置图片样式image/resize,m_fixed,w_500,h_500)
	 * @param objectKey
	 * @return
	 * @throws ClientException
	 */
	public String getBrowseUrl(String objectKey) throws ClientException {
		// 此处必须为 HTTPS
		//if(response==null)
			response = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy, protocolType);
		String accessKeyIds = response.getCredentials().getAccessKeyId();
		String accessKeySecrets = response.getCredentials().getAccessKeySecret();
		String securityToken = response.getCredentials().getSecurityToken();
		OSSClient client = new OSSClient(endpoint, accessKeyIds, accessKeySecrets, securityToken);
		String bucketName = OSSBANKNAME;
		String key = objectKey;//"idcard/20170915095246_224.jpg"
		// 图片处理样式
		String style = "image/resize,m_fixed,w_500,h_500";
		// 设置URL过期时间为1小时
		Date expiration = new Date(new Date().getTime() + 3600 * 1000);
		GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET);
	    req.setExpiration(expiration);
	    req.setProcess(style);
		// 生成URL
		URL url = client.generatePresignedUrl(req);
		String strurl=url.toString();
		return strurl;
	}
}
